/*
 * Copyright (C) 2013 The i18nCTS Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.i18nCTS.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;

public class XmlParser {
	private static final String TAG = "I18nCTS_" + XmlParser.class.getSimpleName();
    private static final String ns = null;

    public List<Entry> parse(InputStream in) throws XmlPullParserException, IOException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            parser.setInput(in, null);
            parser.nextTag();
            return readFeed(parser);
        } finally {
            in.close();
        }
    }

    private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
        List<Entry> entries = new ArrayList<Entry>();

        parser.require(XmlPullParser.START_TAG, ns, "Workbook");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            // Starts by looking for the Row tag
            if (parser.getName().equals("Worksheet")) {
	            	
	            while (parser.next() != XmlPullParser.END_TAG) {
	                if (parser.getEventType() != XmlPullParser.START_TAG) {
	                    continue;
	                }
	                if (parser.getName().equals("Table")) {
	    	            while (parser.next() != XmlPullParser.END_TAG) {
	    	                if (parser.getEventType() != XmlPullParser.START_TAG) {
	    	                    continue;
	    	                }
	    	                if (parser.getName().equals("Row")) {
	    	    	            while (parser.next() != XmlPullParser.END_TAG) {
	    	    	                if (parser.getEventType() != XmlPullParser.START_TAG) {
	    	    	                    continue;
	    	    	                }
	    	    	                if (parser.getName().equals("Cell")) {
	    	    		                entries.add(readEntry(parser));
	    	    		            } else {
	    	    		                skip(parser);
	    	    		            }
	    	    	            }	            	            
	    		            } else {
	    		                skip(parser);
	    		            }
	    	            }	            	            
		            } else {
		                skip(parser);
		            }
	            }	            	            
            } else {
                skip(parser);
            }
        }
        return entries;
    }

    // It includes the data members "Row" "Cell"
    public static class Entry {
        public final String mCell;

        private Entry(String cell) {
            this.mCell = cell;
        }
    }

    // Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them
    // off
    // to their respective &quot;read&quot; methods for processing. Otherwise, skips the tag.
    private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
        parser.require(XmlPullParser.START_TAG, ns, "Cell");
        String cell = "";
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
            if (name.equals("Data")) {
            	cell = readData(parser);
            } else {
                skip(parser);
            }
        }
        return new Entry(cell);
    }

    // Processes title tags in the feed.
    private String readData(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "Data");
        String data = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "Data");
        return data;
    }

    // For the tags, extract their text values.
    private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
        String result = "";
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.getText();
            parser.nextTag();
        }
        return result;
    }

    // Skips tags the parser isn't interested in. Uses depth to handle nested tags. i.e.,
    // if the next tag after a START_TAG isn't a matching END_TAG, it keeps going until it
    // finds the matching END_TAG (as indicated by the value of "depth" being 0).
    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            throw new IllegalStateException();
        }
        int depth = 1;
        while (depth != 0) {
            switch (parser.next()) {
            case XmlPullParser.END_TAG:
                    depth--;
                    break;
            case XmlPullParser.START_TAG:
                    depth++;
                    break;
            }
        }
    }
}
